/*
 * CVisualisator.h
 *
 *  Created on: 04.09.2011
 *      Author: Blinov Kirill
 *      Copyright: LGPL
 */

#ifndef CVISUALISATOR_H_
#define CVISUALISATOR_H_

#include "../TThreadSafeQueue.h"
#include "../BasicTypes.h"
#include "CCameraPreprocessor.h"
#include "CRenderer.h"
#include "CFrameBuffer.h"
#include "ShaderTypes.h"
#include <vector>
#include <boost/function.hpp>
//#include "Manager Resource/ManagerResource.h"

/*
 *
 */
class CVisualisator
{
private:
	bool                            initialized;
	CCameraPreprocessor*            cameraPreprocessor;
	CRenderer*                      renderer;

protected:
	GLuint LoadShader( const std::string FileName, const GLenum ShaderType, std::string** ShaderSource );
	bool CheckShader( const GLuint ShaderName, const char* Source );
	bool CheckProgram(GLuint ProgramName);
	std::string* LoadFile( const std::string& Filename );
public:
	CVisualisator();
	virtual ~CVisualisator();

	bool StartVisualisation( TThreadSafeQueue<FULL_FRAME_DATA*>* FrameQueue, TThreadSafeQueue<INPUT_MESSAGE*> *InputMessageQueue );
	void StopVisualisation();
	void ConfigVisualisation( );
	void SetDimension( const SCREEN_DIMENSION &ScreenDimension );

    bool LinkShaderProgramm( const GLuint VertexShaderName, const GLuint PixelShaderName, IShaderProgram **Shader );
    bool DefineShaderInputParam( IShaderProgram *Shader, const std::string Parameter, const SHADER_INPUT_COMMON_VALUES CommonValue );
    template <class ConstClass>
    bool DefineShaderInputParam( IShaderProgram *Shader, const std::string Parameter, const ConstClass Value );
    template <class FunctionResult>
    bool DefineShaderInputParam( IShaderProgram *Shader, const std::string Parameter, boost::function <FunctionResult()> Value );

	GLuint SetUpModels( const std::vector<PURE_COMPRESSED_MODEL> &ProcessedModels ); //TODO Вынести всю эту загрузку в отдельный файл
    GLuint SetUpShader( const std::string FileName );//TODO Вынести всю эту загрузку в отдельный файл
    void DeleteTexture( const GLuint Name );//TODO Вынести всю эту загрузку в отдельный файл
    void DeleteTexture( const std::vector<GLuint> Names );//TODO Вынести всю эту загрузку в отдельный файл
    void DeleteVertexBuffer( const GLuint Name );//TODO Вынести всю эту загрузку в отдельный файл
    void DeleteVertexBuffer( const std::vector<GLuint> Name ); //TODO Вынести всю эту загрузку в отдельный файл
};

template <class ConstClass>
bool
CVisualisator::DefineShaderInputParam( IShaderProgram *Shader, const std::string Parameter, const ConstClass Value )
{
    GLint Reference = Shader->GetShaderParamReference( Parameter );
	bool Result = ( Reference > 0 );

	if ( Result )
	{
		IShaderParamContainer* Container = new CShaderParamConstant<ConstClass>( Reference, Value );
		Shader->AddParamContainer( Container );
	}

	return Result;
}

template <class FunctionResult>
bool
CVisualisator::DefineShaderInputParam( IShaderProgram *Shader, const std::string Parameter,
                             boost::function <FunctionResult()> Value )
{
    GLint Reference = Shader->GetShaderParamReference( Parameter );
	bool Result = ( Reference > 0 );

	if ( Result )
	{
		IShaderParamContainer* Container = new CShaderParamCallback<FunctionResult>( Reference, Value );
		Shader->AddParamContainer( Container );
	}

	return Result;
}


#endif /* CVISUALISATOR_H_ */
